﻿﻿using UnityEngine;
using System;

namespace Lockstep.UI
{
	public class StatsBar : MonoBehaviour
	{
		[SerializeField] private BarElement _shield;
		[SerializeField] private BarElement _health;
		[SerializeField] private BarElement _energy;

        [SerializeField]
        Vector3 _offset;
        Vector3 Offset { get { return _offset; } }

		public LSAgent TrackedAgent { get; private set; }
        public Health HealthComp { get; private set; }
        public Energy EnergyComp { get; private set; }

		void Awake()
		{
			gameObject.SetActive(false);
		}

		public void Setup(LSAgent agent)
		{
			TrackedAgent = agent;
            HealthComp = agent.GetAbility<Health>();
            HealthComp.onHealthChange += OnHealthChange;
            HealthComp.onDie += OnDie;

            EnergyComp = agent.GetAbility<Energy>();
            EnergyComp.onEnergyChange += OnEnergyChange;
            //GameObject.DontDestroyOnLoad(gameObject);
            this.gameObject.name = agent.ToString();
            Initialize();
		}

        private void OnHealthChange()
        {
            var doubleHealthAmount = HealthComp.HealthAmount * 1.0;
            var doubleMaxHealthAmout = HealthComp.MaxHealth * 1.0;
            SetFill(StatBarType.Health, (float)(doubleHealthAmount / doubleMaxHealthAmout));
        }

        private void OnEnergyChange()
        {
            var doubleEnergyAmount = EnergyComp.EnergyAmount * 1.0;
            var doubleMaxEnergyAmount = EnergyComp.MaxEnergy * 1.0;
            SetFill(StatBarType.Energy, (float)(doubleEnergyAmount / doubleMaxEnergyAmount));
        }

        private void OnDie(Health health, AttackerInfo attakerInfo)
        {
            StatsManager.DestroyStatsBar(this);
        }

        private static StatBarType[] statTypes = (StatBarType[])Enum.GetValues(typeof(StatBarType));

		public void Initialize()
		{
			gameObject.SetActive(true);
			UpdatePos();
			//UpdateScale();
		}

		public void Visualize()
		{
            if (RTSInterfacingHelper.GUIManager.CameraChanged && TrackedAgent.IsVisible)
            {
                this.UpdatePos();
                //this.UpdateScale();
            }
			
			else if (TrackedAgent.VisualPositionChanged)
			{
				this.UpdatePos();
			}
		}

		static GUIManager GUIManager { get { return RTSInterfacingHelper.GUIManager; } }
		static Camera MainCam { get { return GUIManager.MainCam; } }

		static Vector3 screenPos;

		private void UpdatePos()
		{
			if (GUIManager.CanHUD == false) return;
			screenPos = MainCam.WorldToScreenPoint(TrackedAgent.VisualCenter.position + Offset);
			transform.position = screenPos;
		}

		static Vector3 tempScale;

		private void UpdateScale()
		{
			if (GUIManager.CanHUD == false) return;
			float scale = Mathf.Max(TrackedAgent.SelectionRadius / 1f, .1f);
			tempScale.x = GUIManager.CameraScale * scale;
			tempScale.y = GUIManager.CameraScale;
			transform.localScale = tempScale;
		}

		public void SetFill(StatBarType statType, float amount)
		{
			BarElement element = null;
			switch (statType)
			{
				case StatBarType.Shield:
					element = _shield;
					break;
				case StatBarType.Health:
					element = _health;
					break;
				case StatBarType.Energy:
					element = _energy;
					break;
			}
			if (TrackedAgent.IsVisible == false || (amount >= 1f && !GUIManager.ShowHealthWhenFull))
			{
                element.gameObject.SetActive(false);
				return;
			}
			{
				element.SetFill(amount);
				element.gameObject.SetActive(true);
			}
		}

		public void Deactivate()
		{
			if (gameObject == null) return;
			gameObject.SetActive(false);
		}
	}

	public enum StatBarType
	{
		Shield,
		Health,
		Energy
	}
}